//
//  NSMutableArray+Safe.m
//  DebugDemo
//
//  Created by XFB on 2018/11/9.
//  Copyright © 2018年 ZhouCheng. All rights reserved.
//  应该不需要完善了 此分类

#import "NSMutableArray+Safe.h"
#import "NSObject+Swizzling.h"

/// 可变数组
static NSString *KMutableArrayClass = @"__NSArrayM";

@implementation NSMutableArray (Safe)

+ (void)load
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        /// 根据索引获取对象
        [objc_getClass("__NSArrayM") swizzleSelector:@selector(objectAtIndex:)
                                        withSwizzledSelector:@selector(zc_safeObjectAtIndex:)];
        /// 根据索引取对象
        [objc_getClass("__NSArrayM") swizzleSelector:@selector(objectAtIndexedSubscript:)
                                        withSwizzledSelector:@selector(zc_safeObjectAtIndexedSubscript:)];
        /// 删除对象
        [self swizzleSelector:@selector(removeObject:) withSwizzledSelector:@selector(zc_safeRemoveObject:)];
        
        /// 添加对象
        [objc_getClass("__NSArrayM") swizzleSelector:@selector(addObject:)
                                        withSwizzledSelector:@selector(zc_safeAddObject:)];
        /// 根据索引移除对象
        [objc_getClass("__NSArrayM") swizzleSelector:@selector(removeObjectAtIndex:)
                                        withSwizzledSelector:@selector(zc_safeRemoveObjectAtIndex:)];
        /// 插入对象
        [objc_getClass("__NSArrayM") swizzleSelector:@selector(insertObject:atIndex:)
                                        withSwizzledSelector:@selector(zc_safeInsertObject:atIndex:)];
        /// 替换对象
        [objc_getClass("__NSArrayM") swizzleSelector:@selector(replaceObjectAtIndex:withObject:)
                                withSwizzledSelector:@selector(zc_safeReplaceObjectAtIndex:withObject:)];

        /// 移除某个范围内元素
        [objc_getClass("__NSArrayM") swizzleSelector:@selector(removeObjectsInRange:)
                                withSwizzledSelector:@selector(zc_safeRemoveObjectsInRange:)];
    });
}

///
- (void)zc_safeRemoveObjectsInRange:(NSRange)range
{
    if (range.location > self.count) {
        return ;
    }

    if (range.length > self.count) {
        return ;
    }

    if ((range.location + range.length) > self.count) {
        return ;
    }

    return [self zc_safeRemoveObjectsInRange:range];
}

- (id)zc_safeObjectAtIndex:(NSUInteger)index
{
    if (self.count == 0 || index > self.count) {
        @try {
            return [self zc_safeObjectAtIndex:index];
        } @catch (NSException *exception) {
            /// 抛出异常
            NSLog(@"%@", [exception callStackSymbols]);
            return nil;
        } @finally {}
    } else {
        return [self zc_safeObjectAtIndex:index];
    }
}

- (id)zc_safeObjectAtIndexedSubscript:(NSUInteger)index
{
    if (self.count == 0 || index >= self.count) {
        @try {
            return [self zc_safeObjectAtIndexedSubscript:index];
        } @catch (NSException *exception) {
            /// 抛出异常
            NSLog(@"%@", [exception callStackSymbols]);
            return nil;
        } @finally {}
    } else {
        return [self zc_safeObjectAtIndexedSubscript:index];
    }
}

- (void)zc_safeAddObject:(id)object
{
    if (object == nil) {
        @try {
            [self zc_safeAddObject:object];
        } @catch (NSException *exception) {
            /// 抛出异常
            NSLog(@"%@", [exception callStackSymbols]);
        } @finally {}
    } else {
        [self zc_safeAddObject:object];
    }
}

- (void)zc_safeRemoveObject:(id)object
{
    if (object == nil) {
        @try {
            [self zc_safeRemoveObject:object];
        } @catch (NSException *exception) {
            /// 抛出异常
            NSLog(@"%@", [exception callStackSymbols]);
        } @finally {}
    } else {
        [self zc_safeRemoveObject:object];
    }
}

- (void)zc_safeInsertObject:(id)anObject atIndex:(NSUInteger)index
{
    if (anObject == nil || index > self.count) {
        @try {
            [self zc_safeInsertObject:anObject atIndex:index];
        } @catch (NSException *exception) {
            /// 抛出异常
            NSLog(@"%@", [exception callStackSymbols]);
        } @finally {}
    } else {
        [self zc_safeInsertObject:anObject atIndex:index];
    }
}

- (void)zc_safeRemoveObjectAtIndex:(NSUInteger)index
{
    if (self.count <= 0 || index >= self.count) {
        @try {
            [self zc_safeRemoveObjectAtIndex:index];
        } @catch (NSException *exception) {
            /// 抛出异常 __throwOutException
            NSLog(@"%@", [exception callStackSymbols]);
        } @finally {}
    } else {
        [self zc_safeRemoveObjectAtIndex:index];
    }
}

/// 字符串替换
- (void)zc_safeReplaceObjectAtIndex:(NSUInteger)index withObject:(id)anObject
{
    if (anObject == nil || index > self.count) {
        @try {
            [self zc_safeReplaceObjectAtIndex:index withObject:anObject];
        } @catch (NSException *exception) {
            /// 抛出异常
            NSLog(@"%@", [exception callStackSymbols]);
        } @finally {}
    } else {
        [self zc_safeReplaceObjectAtIndex:index withObject:anObject];
    }
}


@end
